package adminDynamicFieldService

import (
	"encoding/json"

	adminDynamicFieldEntry "gitee.com/krio/ginc/example/internal/admin/dynamic/field/entry"

	"gitee.com/krio/ginc/example/core/exerr"
	exampleDtoApiPbAdminDynamicField "gitee.com/krio/ginc/example/dto/api/pb/admin/dynamic_field"
	adminDynamicFieldDao "gitee.com/krio/ginc/example/internal/admin/dynamic/field/dao"
	adminDynamicFieldModel "gitee.com/krio/ginc/example/internal/admin/dynamic/field/model"
	commonEntry "gitee.com/krio/ginc/example/internal/common/entry/common"
	commonModel "gitee.com/krio/ginc/example/internal/common/model/common"
	"github.com/gin-gonic/gin"
)

// DynamicFieldList 列表
func DynamicFieldList(ctx *gin.Context, req *exampleDtoApiPbAdminDynamicField.DynamicFieldListReq) (*exampleDtoApiPbAdminDynamicField.DynamicFieldListResp, error) {
	resp := &exampleDtoApiPbAdminDynamicField.DynamicFieldListResp{}
	search := struct {
		Keyword string `json:"keyword"`
	}{}
	if req.Keywords != "" {
		err := json.Unmarshal([]byte(req.Keywords), &search)
		if err != nil {
			return nil, err
		}
	}
	dao := &adminDynamicFieldDao.DynamicFieldDao{}
	list, total, err := dao.DynamicFieldList(ctx, &commonEntry.ListCommonReq{
		Page:    req.Page,
		Limit:   req.Limit,
		Keyword: search.Keyword,
		OrderBy: []*commonEntry.OrderBy{
			{
				IsDesc: true,
				Field:  "id",
			},
		},
	})
	if err != nil {
		return nil, err
	}
	var data []*exampleDtoApiPbAdminDynamicField.DynamicFieldInfo
	for _, v := range list {
		data = append(data, model2info(v))
	}
	resp.Total = total
	resp.List = data
	return resp, nil
}

// DynamicFieldDetail 详情
func DynamicFieldDetail(ctx *gin.Context, req *exampleDtoApiPbAdminDynamicField.DynamicFieldDetailReq) (*exampleDtoApiPbAdminDynamicField.DynamicFieldInfo, error) {
	dao := &adminDynamicFieldDao.DynamicFieldDao{}
	detail, has, err := dao.DynamicFieldDetail(ctx, req.Id)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, exerr.DataNotFound
	}

	return model2info(detail), nil
}

// DynamicFieldAdd 新增
func DynamicFieldAdd(ctx *gin.Context, req *exampleDtoApiPbAdminDynamicField.DynamicFieldInfo) (*exampleDtoApiPbAdminDynamicField.DynamicFieldAddResp, error) {
	one, err := info2model(req)
	if err != nil {
		return nil, err
	}
	dao := &adminDynamicFieldDao.DynamicFieldDao{}
	id, err := dao.DynamicFieldAdd(ctx, one)
	if err != nil {
		return nil, err
	}
	return &exampleDtoApiPbAdminDynamicField.DynamicFieldAddResp{
		Id: id,
	}, nil
}

// DynamicFieldUpdate 修改
func DynamicFieldUpdate(ctx *gin.Context, req *exampleDtoApiPbAdminDynamicField.DynamicFieldInfo) (*exampleDtoApiPbAdminDynamicField.DynamicFieldAddResp, error) {
	one, err := info2model(req)
	if err != nil {
		return nil, err
	}
	dao := &adminDynamicFieldDao.DynamicFieldDao{}
	_, err = dao.DynamicFieldUpdate(ctx, one)
	if err != nil {
		return nil, err
	}
	return &exampleDtoApiPbAdminDynamicField.DynamicFieldAddResp{}, nil
}

// DynamicFieldDelete 删除
func DynamicFieldDelete(ctx *gin.Context, req *exampleDtoApiPbAdminDynamicField.DynamicFieldDeleteReq) (*exampleDtoApiPbAdminDynamicField.DynamicFieldDeleteResp, error) {
	dao := &adminDynamicFieldDao.DynamicFieldDao{}
	err := dao.DynamicFieldDelete(ctx, req.Ids)
	if err != nil {
		return nil, err
	}
	return &exampleDtoApiPbAdminDynamicField.DynamicFieldDeleteResp{}, nil
}

// 数据装换
func model2info(v *adminDynamicFieldModel.DynamicField) *exampleDtoApiPbAdminDynamicField.DynamicFieldInfo {
	return &exampleDtoApiPbAdminDynamicField.DynamicFieldInfo{
		Id:                  v.ID,
		Label:               v.Label,
		Key:                 v.Key,
		Attr:                v.Attr,
		WebType:             v.WebType,
		DateFormat:          v.DateExt.Format,
		DateSpaceMarkFirst:  v.DateExt.SpaceMarkFirst,
		DateSpaceMarkSecond: v.DateExt.SpaceMarkSecond,
		DateHasSpace:        v.DateExt.HasSpace.ToString(),
		BindEnumKey:         v.SelectExt.BindEnumKey,
		Remark:              v.Remark,
		DefaultValue:        v.DefaultValue,
		Required:            v.Required.ToString(),
		Status:              int32(v.Status),
		CreateTime:          v.CreatedAt.Format("2006-01-02 15:04:05"),
		UpdateTime:          v.UpdatedAt.Format("2006-01-02 15:04:05"),
	}
}

func info2model(info *exampleDtoApiPbAdminDynamicField.DynamicFieldInfo) (*adminDynamicFieldModel.DynamicField, error) {
	data := &adminDynamicFieldModel.DynamicField{
		Label:        info.Label,
		Key:          info.Key,
		Attr:         info.Attr,
		WebType:      info.WebType,
		Required:     adminDynamicFieldEntry.FieldBool(info.Required),
		DefaultValue: info.DefaultValue,
		Remark:       info.Remark,
		SelectExt:    adminDynamicFieldEntry.FieldSelect{},
		DateExt:      adminDynamicFieldEntry.FieldDate{},
		Status:       commonModel.DataStatus(info.Status),
	}
	if info.Id > 0 {
		data.Basic = commonModel.Basic{ID: info.Id}
	}
	switch data.Attr {
	case adminDynamicFieldEntry.DateOne.Value, adminDynamicFieldEntry.DateMore.Value: // 日期
		data.DateExt = adminDynamicFieldEntry.FieldDate{
			Format:          info.DateFormat,
			SpaceMarkFirst:  info.DateSpaceMarkFirst,
			SpaceMarkSecond: info.DateSpaceMarkSecond,
			HasSpace:        adminDynamicFieldEntry.FieldBool(info.DateHasSpace),
		}
	case adminDynamicFieldEntry.SelectOne.Value, adminDynamicFieldEntry.SelectMore.Value: // 下拉
		data.SelectExt = adminDynamicFieldEntry.FieldSelect{
			BindEnumKey: info.BindEnumKey,
		}
	}

	return data, nil
}
